﻿using KAs.SeviceRegister.Interface;
using System.Reflection;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class ServiceRegisterExtensions
    {
        /// <summary>
        /// 通过反射，获取依赖注入服务标记接口的实现类，按服务类型分别进行注册
        /// </summary>
        /// <param name="services"></param>
        public static void AddAppServices(this IServiceCollection services)
        {

            // 获取运行目录下所有程序集
            var path = AppDomain.CurrentDomain.BaseDirectory;
            string[] dllFiles = Directory.GetFiles(path, "*.dll", SearchOption.TopDirectoryOnly);

            var assemblies = new List<Assembly>();
            foreach (var item in dllFiles)
            {
                assemblies.Add(Assembly.LoadFrom(item));
            }
            services.ServiceRegister(assemblies.ToArray());
        }

        public static void ServiceRegister(this IServiceCollection services, params Assembly[] assemblies)
        {
            if (assemblies.Length <= 0)
            {
                return;
            }
            foreach (var assembly in assemblies)
            {

                var allTypes = assembly.GetTypes().Where(x => x.IsClass && !x.IsAbstract).ToList();

                foreach (var type in allTypes.FindAll(x => typeof(ITransientDependency).IsAssignableFrom(x)))
                {
                    //  获取当前实现类的接口，但不包含依赖注入标记接口
                    var interfaceTypes = type.GetInterfaces().Where(p => !p.FullName.Contains(typeof(ITransientDependency).Name));
                    foreach (var interfaceType in interfaceTypes)
                    {
                        services.AddTransient(interfaceType, type);
                    }
                }

                foreach (var type in allTypes.FindAll(x => typeof(ISingletonDependency).IsAssignableFrom(x)))
                {
                    //  获取当前实现类的接口，但不包含依赖注入标记接口
                    var interfaceTypes = type.GetInterfaces().Where(p => !p.FullName.Contains(typeof(ISingletonDependency).Name));
                    foreach (var interfaceType in interfaceTypes)
                    {
                        services.AddSingleton(interfaceType, type);
                    }
                }

                foreach (var type in allTypes.FindAll(x => typeof(IScopedDependency).IsAssignableFrom(x)))
                {
                    //  获取当前实现类的接口，但不包含依赖注入标记接口
                    var interfaceTypes = type.GetInterfaces().Where(p => !p.FullName.Contains(typeof(IScopedDependency).Name));
                    foreach (var interfaceType in interfaceTypes)
                    {
                        services.AddScoped(interfaceType, type);
                    }
                }
            }

        }
    }
}
